<script setup lang="ts">
import * as ElIcons from '@element-plus/icons-vue';
import { DataField } from '@formily/core';
import { useField } from '@formily/vue';
import MdiIcon from '@iconify-json/mdi/chars.json';
import { Icon } from '@iconify/vue';
import { usePrefix } from '@season-designable/vue';
import { getIconList } from '.';

const field = useField<DataField>();
const prefix = usePrefix('icon-setter');
const emit = defineEmits(['change']);
const props = defineProps(['value']);

const nameList = props.value.name.split(':');

const defaultValue =
  nameList.length === 1 ? ['element', ...nameList] : nameList;

const collection = ref(defaultValue[0]);
const icon = ref(defaultValue[1]);

const collectionList: Record<string, string[]> = {
  element: Object.keys(ElIcons),
  mdi: Object.values(MdiIcon),
};

const iconDataList = ref(getIconList(collectionList[collection.value]));

const handleCollection = (value: string) => {
  collection.value = value;
  iconDataList.value = getIconList(collectionList[collection.value]);
  icon.value = '';
};

const handleChange = (value: any) => {
  icon.value = value;

  if (collection.value === 'element') {
    const Component = ElIcons[value as keyof typeof ElIcons];
    emit('change', Component);
  } else {
    const Component = defineComponent({
      name: `${collection.value}:${value}`,
      setup() {
        return () =>
          h(Icon, {
            icon: `${collection.value}:${value}`,
          });
      },
    });
    emit('change', Component);
  }
};

const handleFilterMethod = (keyword: string) => {
  iconDataList.value = collectionList[collection.value]
    .filter((item) => item.toLocaleLowerCase().includes(keyword))
    .slice(0, 100)
    .map((iconData) => ({
      label: iconData,
      value: iconData,
    }));
};
</script>

<template>
  <FoldItem :class="prefix" :label="field.title">
    <template #base>
      <ElInput v-model="icon" disabled>
        <template #prefix>
          <Icon
            v-if="collection !== 'element'"
            :icon="collection + ':' + icon"
          />
          <el-icon v-else>
            <component :is="ElIcons[icon as keyof typeof ElIcons]"></component>
          </el-icon>
        </template>
      </ElInput>
    </template>
    <template #extra>
      <InputItems>
        <InputItem icon="mdi:rhombus-split">
          <ElSelect
            :model-value="collection"
            filterable
            @change="handleCollection"
            :style="{ width: '100%' }"
          >
            <ElOption
              v-for="item in Object.keys(collectionList)"
              :key="item"
              :label="item"
              :value="item"
            />
          </ElSelect>
        </InputItem>
        <InputItem icon="mdi:simple-icons">
          <ElSelect
            :model-value="icon"
            filterable
            @change="handleChange"
            :remote-method="handleFilterMethod"
            remote
            :style="{ width: '100%' }"
          >
            <ElOption
              v-for="item in iconDataList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
              <template #default>
                <span>
                  <Icon
                    v-if="collection !== 'element'"
                    :icon="collection + ':' + item.value"
                  />
                  <el-icon v-else>
                    <component
                      :is="ElIcons[item.value as keyof typeof ElIcons]"
                    ></component>
                  </el-icon>
                </span>
                <span :style="{ paddingLeft: '8px' }"> {{ item.label }} </span>
              </template>
            </ElOption>
            <template #prefix>
              <Icon
                v-if="collection !== 'element'"
                :icon="collection + ':' + icon"
              />
              <el-icon v-else>
                <component
                  :is="ElIcons[icon as keyof typeof ElIcons]"
                ></component>
              </el-icon>
            </template>
          </ElSelect>
        </InputItem>
      </InputItems>
    </template>
  </FoldItem>
</template>

<style lang="scss" scoped>
// .dn-icon-setter-cascader {
//   .el-cascader-node__label {
//     display: flex;
//     align-items: center;
//   }
// }
</style>
